#pragma once
#include <string>
#include <functional>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>
#include "InetAddr.hpp"
#include "Log.hpp"
#include "ThreadPool.hpp"

using namespace LogMudule;
using namespace ThreadPoolModual;

const static uint16_t defaultport = 8888;

using task_t=std::function<void()>;

class TCPSever
{
    // 2.进程分离
    void Service(int sockfd)
    {
        char buff[1024];
        while (true)
        {

            // TCP是面向字节流的，故而可以采用文件的接口进行读取和写入
            int n = ::read(sockfd, buff, sizeof(buff) - 1);
            if (n > 0)
            {
                buff[n] = 0;
                std::string message = "Client Say@";
                message += buff;
                int m = ::write(sockfd, message.c_str(), message.size());
                if (m < 0)
                {
                    LOG(LogLevel::ERROR) << "write failed";
                }
            }
            else if (n == 0)
            {
                // 表示读到了文件末尾
                LOG(LogLevel::INFO) << "Client Quit……";
                break;
            }
            else
            {
                LOG(LogLevel::ERROR) << "read error";
                break;
            }
        }
        ::close(sockfd);
    }
public:
    TCPSever(uint16_t port = defaultport) : _addr(port)
    {
        // 创建套接字
        int n = _listensockfd = ::socket(AF_INET, SOCK_STREAM, 0);
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "socket failed";
            exit(1);
        }
        LOG(LogLevel::INFO) << "socket succeed";
        // 绑定
        n = ::bind(_listensockfd, _addr.NetAddr(), _addr.Len());
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "bind failed";
            exit(1);
        }
        LOG(LogLevel::INFO) << "bind succeed";
        // 开始监听
        n = ::listen(_listensockfd, 1);
        if (n < 0)
        {
            LOG(LogLevel::FATAL) << "listen failed";
            exit(1);
        }
        LOG(LogLevel::INFO) << "listen succeed";
    }

    void Run()
    {
        while (true)
        {
            // // 4.线程池管理版本
            // struct sockaddr_in connected_addr;
            // socklen_t len = sizeof(connected_addr);
            // int sockfd = ::accept(_listensockfd, (struct sockaddr *)&connected_addr, &len);
            // if (sockfd < 0)
            // {
            //     LOG(LogLevel::ERROR) << "accept failed";
            //     continue;
            // }

            // InetAddr peer(connected_addr);
            // LOG(LogLevel::INFO) << "accept succeed connected is " << peer.Addr() << " sockfd is " << sockfd;

            // //绑定生成任务
            // task_t task=std::bind(&TCPSever::Service,this,sockfd);
            // ThreadPool<task_t> ::GetInstance()->Enqueue(task);
        }
    }
    ~TCPSever()
    {
        ::close(_listensockfd);
    }

private:
    int _listensockfd;
    InetAddr _addr;
};
